﻿Imports System.Drawing
Imports System.Windows.Forms
Public Module mdlEditor
#Region "内部变量"
    ''' <summary>
    ''' 最小长度
    ''' </summary>
    ''' <remarks></remarks>
    Public mSingleLineMinLength As Byte
    ''' <summary>
    ''' 最大长度
    ''' </summary>
    ''' <remarks></remarks>
    Public mSingleLineMaxLength As Byte
    ''' <summary>
    ''' 背景颜色
    ''' </summary>
    ''' <remarks></remarks>
    Public ExBackColor As Color = Color.White
    ''' <summary>
    ''' 标尺
    ''' </summary>
    ''' <remarks></remarks>
    Public ExRulerColor As Color = Color.WhiteSmoke
    ''' <summary>
    ''' 选中部分背景色
    ''' </summary>
    ''' <remarks></remarks>
    Public ExSelectionBackColor As Color = Color.Blue
    ''' <summary>
    ''' 选中部分文字色
    ''' </summary>
    ''' <remarks></remarks>
    Public ExSelectionForeColor As Color = Color.White
    ''' <summary>
    ''' 文字颜色
    ''' </summary>
    ''' <remarks></remarks>
    Public ExForeColor As Color = Color.Black
    ''' <summary>
    ''' 注释颜色
    ''' </summary>
    ''' <remarks></remarks>
    Public ExCommentColor As Color = Color.Green
    ''' <summary>
    ''' 引用字符的颜色
    ''' </summary>
    ''' <remarks></remarks>
    Public ExQuateColor As Color = Color.Orange
    ''' <summary>
    '''  公用的字体
    ''' </summary>
    ''' <remarks></remarks>
    Public ExFont As Font
    ''' <summary>
    ''' 横向偏移
    ''' </summary>
    ''' <remarks></remarks>
    Public offset As Integer
    ''' <summary>
    ''' 水平位移的最小单位
    ''' </summary>
    ''' <remarks></remarks>
    Public offsetUnit As Byte
    ''' <summary>
    ''' 1个Tab换多少个空格
    ''' </summary>
    ''' <remarks></remarks>
    Public TabSpace As Byte = 4
    ''' <summary>
    ''' 公用的图形对象
    ''' </summary>
    ''' <remarks></remarks>
    Friend ShareG As Graphics
    ''' <summary>
    ''' 第一个可见行的显示行号
    ''' </summary>
    ''' <remarks></remarks>
    Friend FirstVisiableLineNumber As Integer
    ''' <summary>
    ''' 可见行数
    ''' </summary>
    ''' <remarks></remarks>
    Friend VisibleLines As Byte
    ''' <summary>
    ''' 文档类
    ''' </summary>
    ''' <remarks></remarks>
    Public ExDocument As New Document(Encoding.Default)
    ''' <summary>
    ''' 是否处于列模式
    ''' </summary>
    ''' <remarks></remarks>
    Public ExColumnMode As Boolean
    ''' <summary>
    ''' 是否处于折行模式
    ''' </summary>
    ''' <remarks></remarks>
    Public ExWordWrapMode As Boolean
    ''' <summary>
    ''' 是否处于箱型选择模式
    ''' </summary>
    ''' <remarks></remarks>
    Public ExBoxSelectMode As Boolean
    ''' <summary>
    ''' 是否出于只读模式
    ''' </summary>
    ''' <remarks></remarks>
    Public ExReadOnlyMode As Boolean
#End Region
#Region "结构和枚举"
    ''' <summary>
    ''' 输入法模式
    ''' </summary>
    ''' <remarks></remarks>
    Public Enum EnumInputMode
        InsertChar                     '插入
        OverwriteChar                  '更新
    End Enum
    ''' <summary>
    ''' 垂直设定[考虑使用.Net的默认枚举]
    ''' </summary>
    ''' <remarks></remarks>
    Public Enum VPosition
        Top
        Middle
        Bottom
    End Enum
    ''' <summary>
    ''' 单个单词的构造
    ''' </summary>
    ''' <remarks></remarks>
    Public Structure SingleWord
        Dim StrWord As String   '单词
        Dim Pos As Point        '起始位置
        Dim Length As Integer   '长度
    End Structure
#End Region
#Region "全局方法"
    ''' <summary>
    ''' 获得字符串长度
    ''' </summary>
    ''' <param name="strText"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Friend Function MeasureSingleTextWidth(ByVal strText As String) As Single
        If strText = String.Empty Then Return 0
        Dim MethodType As Boolean
        MethodType = True
        If MethodType Then
            Dim strflg As StringFormat
            strflg = StringFormat.GenericTypographic
            strflg.FormatFlags = StringFormatFlags.MeasureTrailingSpaces
            Return ShareG.MeasureString(strText, ExFont, 10000, strflg).Width
        Else
            'Graphics的字符测量MeasureString，有多余的尾部空白
            'MeasureText:将边框设定为0，TextFormatFlags：NoPadding 不在边框中添加空白边距
            '为了防止 & 字符的 热键，需要设定 NoPrefix
            Dim strflg As TextFormatFlags
            strflg = TextFormatFlags.NoPadding Or TextFormatFlags.NoPrefix
            Return TextRenderer.MeasureText(ShareG, strText, ExFont, New Size(0, 0), strflg).Width
        End If
    End Function
    ''' <summary>
    ''' 获得字符串长度
    ''' </summary>
    ''' <param name="strText"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Friend Function MeasureTextWidth(ByVal strText As String) As Integer
        If strText = String.Empty Then Return 0
        Dim MethodType As Boolean
        MethodType = True
        If MethodType Then
            Dim strflg As StringFormat
            strflg = StringFormat.GenericTypographic
            strflg.FormatFlags = StringFormatFlags.MeasureTrailingSpaces
            Return CInt(ShareG.MeasureString(strText, ExFont, 10000, strflg).Width)
        Else
            'Graphics的字符测量MeasureString，有多余的尾部空白
            'MeasureText:将边框设定为0，TextFormatFlags：NoPadding 不在边框中添加空白边距
            '为了防止 & 字符的 热键，需要设定 NoPrefix
            Dim strflg As TextFormatFlags
            strflg = TextFormatFlags.NoPadding Or TextFormatFlags.NoPrefix
            Return CInt(TextRenderer.MeasureText(ShareG, strText, ExFont, New Size(0, 0), strflg).Width)
        End If
    End Function
    ''' <summary>
    ''' 通过鼠标位置获得表示插入点
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetDisplayPosByMouse(ByVal MousePos As Point) As Point
        MousePos.X += offset
        '最后表示行和列以外的时候，则什么都不做
        If Math.Ceiling(MousePos.Y / ExFont.Height) > ExDocument.MaxDisplayLineNumber - FirstVisiableLineNumber + 1 Then
            Return New Point(ExDocument.GetMemoryLine(ExDocument.MaxDisplayLineNumber).Text.Length + 1, _
                             ExDocument.MaxDisplayLineNumber)
        Else
            Dim TempX As Integer
            Dim TempY As Integer
            TempY = Math.Ceiling(MousePos.Y / ExFont.Height) + FirstVisiableLineNumber - 1
            If TempY < 1 Then TempY = 1
            If ExDocument.GetMemoryLineByDisplayLineNumber(TempY).Text = "" Then
                TempX = 1
            Else
                Dim strText As String = ExDocument.GetMemoryLineByDisplayLineNumber(TempY).Text
                If MeasureTextWidth(strText) <= MousePos.X Then
                    TempX = strText.Length + 1
                Else
                    Dim MidPos As Single
                    For Xpos As Integer = 1 To strText.Length
                        If MeasureTextWidth(Mid(strText, 1, Xpos)) > MousePos.X Then
                            MidPos = (MeasureTextWidth(Mid(strText, 1, Xpos)) + MeasureTextWidth(Mid(strText, 1, Xpos - 1))) / 2
                            If MousePos.X < MidPos Then
                                TempX = Xpos
                            Else
                                TempX = Xpos + 1
                            End If
                            Exit For
                        End If
                    Next
                End If
            End If
            Return New Point(TempX, TempY)
        End If
    End Function
#End Region
#Region "语言配置"
    ''' <summary>
    ''' ToolTip字典
    ''' </summary>
    ''' <remarks></remarks>
    Public tblToolTip As New Dictionary(Of String, String)
    ''' <summary>
    ''' 智能完成字典
    ''' </summary>
    ''' <remarks></remarks>
    Public AutoFillWordList As New Dictionary(Of String, String)
    ''' <summary>
    ''' 上色字典
    ''' </summary>
    ''' <remarks></remarks>
    Public ColorfulWord As New Dictionary(Of String, Color)
    ''' <summary>
    ''' 单行注释符号
    ''' </summary>
    ''' <remarks></remarks>
    Public SingleCommentMark As String
    ''' <summary>
    ''' 注释块开始符号
    ''' </summary>
    ''' <remarks></remarks>
    Public BlockCommentStartMark As String
    ''' <summary>
    ''' 注释块结束符号
    ''' </summary>
    ''' <remarks></remarks>
    Public BlockCommentEndMark As String
    ''' <summary>
    ''' 单词分割标志字符
    ''' </summary>
    ''' <remarks></remarks>
    Public DelimitMark As New List(Of String)
    ''' <summary>
    ''' 代码折叠
    ''' </summary>
    ''' <remarks></remarks>
    Public ExSyntaxKeyList As New List(Of SyntaxKey)
#End Region
#Region "Point比较的方法"
    Enum CompareResult
        Big
        Small
        Equal
    End Enum
    ''' <summary>
    ''' 比较两个Point对象的大小
    ''' </summary>
    ''' <param name="pos1"></param>
    ''' <param name="pos2"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function ComparePoint(ByVal pos1 As Point, ByVal pos2 As Point) As CompareResult
        If pos1.Y > pos2.Y Then Return CompareResult.Big
        If pos1.Y < pos2.Y Then Return CompareResult.Small
        If pos1.X = pos2.X Then Return CompareResult.Equal
        If pos1.X > pos2.X Then Return CompareResult.Big
        Return CompareResult.Small
    End Function
    ''' <summary>
    ''' 获得比较小的那个点
    ''' </summary>
    ''' <param name="pos1"></param>
    ''' <param name="pos2"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function MinPoint(ByVal pos1 As Point, ByVal pos2 As Point) As Point
        Select Case ComparePoint(pos1, pos2)
            Case CompareResult.Equal
                Return pos1
            Case CompareResult.Small
                Return pos1
            Case CompareResult.Big
                Return pos2
        End Select
    End Function
    ''' <summary>
    ''' 获得比较小的那个点
    ''' </summary>
    ''' <param name="pos1"></param>
    ''' <param name="pos2"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function MaxPoint(ByVal pos1 As Point, ByVal pos2 As Point) As Point
        Select Case ComparePoint(pos1, pos2)
            Case CompareResult.Equal
                Return pos1
            Case CompareResult.Small
                Return pos2
            Case CompareResult.Big
                Return pos1
        End Select
    End Function
#End Region
End Module
